﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace PlayListClient
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        TcpListener socketServer;
        string rootDic;
        System.Windows.Forms.NotifyIcon notifyIcon;

        public MainWindow()
        {
            InitializeComponent();
            IPEndPoint ipEndPoint = new IPEndPoint(
                System.Net.IPAddress.Any,VCLib.Util.ConfigHelp.ReadConfig<int>("Port"));
            rootDic = VCLib.Util.ConfigHelp.ReadConfig("RootDirectory");
            socketServer = new TcpListener(ipEndPoint);
            socketServer.Start(1000);
            socketServer.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTcpclient), socketServer);//异步接收 递归循环接收多个客户端
            logWrite("");
            logWrite(rootDic);
            logWrite(ipEndPoint.ToString());
            logWrite(VCLib.Util.ConfigHelp.ReadConfig("dataFileName"));
            logWrite("服务已开启");
            NotifyInit();
        }
        //异步回调方法
        private void DoAcceptTcpclient(IAsyncResult ar)
        {
            // Get the listener that handles the client request.
            TcpListener listener = (TcpListener)ar.AsyncState;

            // End the operation and display the received data on 
            // the console.
            TcpClient client = listener.EndAcceptTcpClient(ar);


            // Process the connection here. (Add the client to a
            // server table, read data, etc.)
            logWrite(string.Format("Client connected completed,id:{0}", client.Client.RemoteEndPoint.ToString()));
            //开启线程用来不断接收来自客户端的数据
            Thread t = new Thread(new ParameterizedThreadStart(ReceiveMessageFromClient));
            t.Start(client);

            socketServer.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTcpclient), socketServer);
        }
        private  void ReceiveMessageFromClient(object reciveClient)
        {
            TcpClient client = reciveClient as TcpClient;
            if (client == null)
            {
                Console.WriteLine("client error");
                return;
            }
            while (true)
            {
                try
                {
                    NetworkStream stream = client.GetStream();
                    logWrite("waiting for data...");
                    byte[] result = new byte[1024];
                    int num = stream.Read(result, 0, result.Length); //将数据读到result中                  
                    if (num != 0)
                    {
                        string str = Encoding.UTF8.GetString(result, 0, num);//只将流中读到的数据长度转换为字符串
                        logWrite(string.Format(str));
                        if (str == "updateDate")
                        {
                            UpdateDate(stream);
                            break;
                        }
                        else if(str == "updateSource")
                        {
                            UpdateSource(stream);
                            break;
                        }
                        else
                        {
                            stream.Write(err,0, err.Length);
                            break;
                        }

                    }
                    else
                    {   //这里需要注意 当num=0时表明客户端已经断开连接，需要结束循环，不然会死循环一直卡住 
                        logWrite("客户端关闭");
                        break;
                    }
                }
                catch (Exception e)
                {
                    logWrite("error:" + e.ToString());
                    break;
                }
          

            }
            try
            {
                client.Close();
            }
            catch
            {

            }

        }
        byte[] ok = new byte[] { 0xa1 };
        byte[] err = new byte[] { 0xa2 };
        byte[] fileExists = new byte[] { 0xa3};
        private void UpdateDate(NetworkStream stream)
        {
            stream.Write(ok, 0, ok.Length);
            Thread.Sleep(50);
            byte[] result = new byte[1024 * 4];
            int len = 0;
            try
            {
                if(!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(VCLib.Util.ConfigHelp.ReadConfig("dataFileName"))))
                {
                    System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(VCLib.Util.ConfigHelp.ReadConfig("dataFileName")));
                }
                logWrite("UpdateDate 开始接收");
                using (System.IO.FileStream fileStream =
                new System.IO.FileStream(VCLib.Util.ConfigHelp.ReadConfig("dataFileName"), FileMode.Create, FileAccess.Write))
                {
                    while ((len = stream.Read(result, 0, result.Length)) > 0)
                    {
                        fileStream.Write(result, 0, len);
                    }
                    //stream.Write(ok, 0, ok.Length);
                    logWrite("UpdateDate 接收完成");
                }
            }
            catch (Exception ex)
            {
                logWrite("UpdateDate ERR："+ex.Message);
                stream.Write(err, 0, err.Length);

            }
            
        }
        private void UpdateSource(NetworkStream stream)
        {
            stream.Write(ok, 0, ok.Length);
            Thread.Sleep(50);
            byte[] result = new byte[1024 * 2];
            int num = stream.Read(result, 0, result.Length); //将数据读到result中      
            string name = Encoding.UTF8.GetString(result, 0, num);//读取文件名
            logWrite("UpdateSource 文件名："+name);
            string fileName = System.IO.Path.Combine(rootDic,name);
            if(System.IO.File.Exists(fileName))
            {
                stream.Write(fileExists, 0, fileExists.Length);
                logWrite("文件已存在");
                return;
            }
            stream.Write(ok, 0, ok.Length);
            try
            {
                logWrite("UpdateDate 开始接收");
                using (System.IO.FileStream fileStream =
                new System.IO.FileStream(fileName, FileMode.Create, FileAccess.Write))
                {
                    int len;
                    while ((len = stream.Read(result, 0, result.Length)) > 0)
                    {
                        fileStream.Write(result, 0, len);
                    }
                    stream.Write(ok, 0, ok.Length);
                    logWrite("UpdateSource 接收完成");
                }
            }
            catch (Exception ex)
            {
                logWrite("UpdateSource ERR：" + ex.Message);
                stream.Write(err, 0, err.Length);

            }

        }
        //private void AcceptTcp(IAsyncResult ar)
        //{
        //    try
        //    {
        //        using (Socket socket = socketServer.EndAccept(ar))//尝试进行异步连接
        //        {
        //            TcpClient client = new TcpClient(socket);
        //            socket.ReceiveBufferSize = 1024;
        //            byte[] buff = new byte[1024];
        //            var size = socket.Receive(buff, 0, SocketFlags.None);
        //            var str = Encoding.UTF8.GetString(buff, 0, size);
        //            logWrite(str);
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        logWrite("AcceptTcp失败:" + e.Message);
        //    }
        //}

        private int logCount;
        private void logWrite(string str)
        {
            VCLib.Util.LogHelp.Write(DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss") + str);
            var log =DateTime.Now.ToString("hh:mm:ss")+"  "+ str + "\n";
            logCount++;
            if (logCount > 300)
            {
                Dispatcher.Invoke(() => {
                    logCount = 0;
                    _ric.Document.Blocks.Clear();
                    _ric.AppendText("\n");
                });
            }
            if (System.Threading.Thread.CurrentThread == Dispatcher.Thread)
            {
                _ric.AppendText(log);
                _ric.ScrollToEnd();
            }
            else
            {
                Dispatcher.Invoke(() => {

                    _ric.AppendText(log);
                    _ric.ScrollToEnd();
                });
            }
        }
        private void NotifyInit()
        {
            /**
            notifyIcon = NotifyIcon.Create();
            this.notifyIcon.ShowBalloonTip("媒体控制服务器", "媒体控制服务器已启动", ToolTipIcon.Info); //设置程序启动时显示的文本
          
            this.notifyIcon.Text = "设备控制服务器";//最小化到托盘时，鼠标点击时显示的文本
            this.notifyIcon.Icon = new System.Drawing.Icon(AppDomain.CurrentDomain.BaseDirectory + "ico2.ico");//程序图标
            
            this.notifyIcon.Visible = true;
            notifyIcon.DoubleClick += NotifyIcon_DoubleClick;
            ContextMenuStrip.MenuItem menu = new ContextMenuStrip.MenuItem();
            menu.Text= "退出系统";
            menu.Click += (s, e) => {
                isClose = true;
                //if(!isClose)
                    
                    this.Close();
            };
            notifyIcon.ContextMenuStrip.Items.Add(menu);

            **/
            notifyIcon = new System.Windows.Forms.NotifyIcon();
            //this.notifyIcon.ShowBalloonTip(3000,"媒体控制服务器", "媒体控制服务器已启动",  System.Windows.Forms.ToolTipIcon.Info); //设置程序启动时显示的文本

            this.notifyIcon.Text = "设备控制服务器";//最小化到托盘时，鼠标点击时显示的文本
            this.notifyIcon.Icon = new System.Drawing.Icon(AppDomain.CurrentDomain.BaseDirectory + "ico1.ico");//程序图标

            this.notifyIcon.Visible = true;
            notifyIcon.DoubleClick += NotifyIcon_DoubleClick;
            System.Windows.Forms.MenuItem menu = new System.Windows.Forms.MenuItem();
            notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu();
            notifyIcon.ContextMenu.MenuItems.Add(menu);
            //ContextMenuStrip.MenuItem menu = new ContextMenuStrip.MenuItem();
            //menu.Text = "退出系统";
            //menu.Click += (s, e) => {
            //    isClose = true;
            //    //if(!isClose)

            //    this.Close();
            //};
            //notifyIcon.ContextMenuStrip.Items.Add(menu);
            this.Visibility= Visibility.Hidden;
        }

        private void NotifyIcon_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                if(this.Visibility == Visibility.Visible)
                {
                    this.Visibility = Visibility.Hidden;
                }
                else
                {
                    this.Visibility = Visibility.Visible;
                }
             

            }
            catch (Exception)
            {

            }
        }

    }
}
